﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Collections.Concurrent;

namespace StepsLib
{
    public partial class Steps : UserControl
    {
       // public string SocketName { get; set; } = "Socket1";
        public List<string> Items { get; set; } = new List<string> { "进度1", "进度2", "进度3", "进度4", "进度5" };
        public Steps()
        {
            InitializeComponent();
        }
        private GraphicsPath GetRoundedRectPath(Rectangle rect)
        {
            Rectangle arcRect = new Rectangle(rect.Location, new System.Drawing.Size(this.Height, this.Height));
            GraphicsPath path = new GraphicsPath();
            Point[] p = new Point[12];

            List<PointF> points = new List<PointF>();
            points.Add(new PointF(3, 0));
            points.Add(new PointF(Width - 3 - Height / 2.0f, 0));
            points.Add(new PointF(Width - 3, Height / 2.0f));
            points.Add(new PointF(Width - 3 - Height / 2.0f, Height));
            points.Add(new PointF(3, Height));
            points.Add(new PointF(3 + Height / 2.0f, Height / 2.0f));
            points.Add(new PointF(3, 0));
            path.AddLine(points[0], points[1]);
            path.AddLine(points[1], points[2]);
            path.AddLine(points[2], points[3]);
            path.AddLine(points[3], points[4]);
            path.AddLine(points[4], points[5]);
            path.AddLine(points[5], points[6]);
            
            path.CloseFigure();
            return path;
        }
        private int interval = 2;
        [DefaultValue(1)]
        [Description("节点间隔"), Category("SunnyUI")]
        public int Interval
        {
            get => interval;
            set
            {
                interval = value;
                Invalidate();
            }
        }

        private bool isMannual = true;
        [DefaultValue(1)]
        [Description("是否为手动模式，手动模式点击鼠标有效，自动模式无效"), Category("SunnyUI")]
        public bool IsMannual
        {
            get => isMannual;
            set
            {
                isMannual = value;
                Invalidate();
            }
        }

        protected Color fillColor = Color.FromArgb(80, 160, 255);
        protected Color rectColor = Color.FromArgb(185, 217, 255);
      
        /// <summary>
        /// 设置填充颜色
        /// </summary>
        /// <param name="value">颜色</param>
        protected void SetFillColor(Color value)
        {
            if (fillColor != value)
            {
                fillColor = value;
                //SetStyleCustom();
            }
        }
        /// <summary>
        ///     已选节点颜色
        /// </summary>
        [Description("已选节点颜色")]
        [Category("SunnyUI")]
        [DefaultValue(typeof(Color), "80, 160, 255")]
        public Color SelectedColor
        {
            get => fillColor;
            set => SetFillColor(value);
        }

        /// <summary>
        ///     未选节点颜色
        /// </summary>
        [Description("未选节点颜色")]
        [Category("SunnyUI")]
        [DefaultValue(typeof(Color), "185, 217, 255")]
        public Color UnSelectedColor
        {
            get => rectColor;
            set => SetRectColor(value);
        }
        /// <summary>
        /// 设置边框颜色
        /// </summary>
        /// <param name="value">颜色</param>
        protected void SetRectColor(Color value)
        {
            if (rectColor != value)
            {
                rectColor = value;
                //SetStyleCustom();
            }
        }
        private Color unSelectedForeColor = Color.White;
        /// <summary>
        ///     未选节点颜色
        /// </summary>
        [Description("未选节点文字颜色")]
        [Category("SunnyUI")]
        [DefaultValue(typeof(Color), "White")]
        public Color UnSelectedForeColor
        {
            get => unSelectedForeColor;
            set
            {
                if (unSelectedForeColor != value)
                {
                    unSelectedForeColor = value;
                    //SetStyleCustom();
                }
            }
        }
        public delegate void OnValueChanged(object sender, int value);

        public event OnValueChanged ItemIndexChanged;
        [Browsable(false)]
        public int Count => Items.Count;
        private int itemIndex = -1;

        [DefaultValue(-1)]
        [Description("当前节点索引"), Category("Steps")]
        public int ItemIndex
        {
            get => itemIndex;
            set
            {
                if (Count == 0)
                {
                    itemIndex = 0;
                }
                else
                {
                    itemIndex = Math.Max(-1, value);
                    itemIndex = Math.Min(Count - 1, value);
                    ItemIndexChanged?.Invoke(this, itemIndex);
                    Invalidate();
                }
            }
        }
        private readonly ConcurrentDictionary<int, Point[]> ClickArea = new ConcurrentDictionary<int, Point[]>();
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            base.OnPaint(e);
            base.OnPaintBackground(e);
            ForeColor = Color.White;
            float width = 0;
            float itemWidth = this.Width;
            if (Items.Count == 0)
            {
                SizeF sf = e.Graphics.MeasureString(Text, Font);
                width = sf.Width + Height + 6;
                if (itemWidth < width) itemWidth = (int)width;
                List<PointF> points = new List<PointF>();
                points.Add(new PointF(3, 0));
                points.Add(new PointF(Width - 3 - Height / 2.0f, 0));
                points.Add(new PointF(Width - 3, Height / 2.0f));
                points.Add(new PointF(Width - 3 - Height / 2.0f, Height));
                points.Add(new PointF(3, Height));
                points.Add(new PointF(3 + Height / 2.0f, Height / 2.0f));
                points.Add(new PointF(3, 0));

                using (Brush br = new SolidBrush(this.BackColor))
                {
                    e.Graphics.FillPolygon(br, points.ToArray());
                }

                e.Graphics.DrawString(Text, Font, new SolidBrush(this.ForeColor),(Width - sf.Width) / 2.0f, (Height - sf.Height) / 2.0f);
            }
            else
            {
                foreach (var item in Items)
                {
                    SizeF sf = e.Graphics.MeasureString(item.ToString(), Font);
                    width = Math.Max(width, sf.Width);
                }
                itemWidth = (this.Width+Height*2+9) / Items.Count();
                width = width + Height + 6;
                if (itemWidth < width) itemWidth = (int)width;

                float begin = 0;
                int index = 0;
                foreach (var item in Items)
                {
                    SizeF sf = e.Graphics.MeasureString(item.ToString(), Font);
                    List<PointF> points = new List<PointF>();

                    if (index == 0 )
                    {
                        points.Add(new PointF(begin + 3, 0));
                        points.Add(new PointF(begin + itemWidth - 3 - Height / 2.0f, 0));
                        points.Add(new PointF(begin + itemWidth - 3, Height / 2.0f));
                        points.Add(new PointF(begin + itemWidth - 3 - Height / 2.0f, Height));
                        points.Add(new PointF(begin + 3, Height));
                        points.Add(new PointF(begin + 3, 0));
                    }
                    else if (index == Items.Count - 1 )
                    {
                        points.Add(new PointF(begin + 3, 0));
                        points.Add(new PointF(begin + itemWidth - 3, 0));
                        points.Add(new PointF(begin + itemWidth - 3, Height));
                        points.Add(new PointF(begin + 3, Height));
                        points.Add(new PointF(begin + 3 + Height / 2.0f, Height / 2.0f));
                        points.Add(new PointF(begin + 3, 0));
                    }
                    else
                    {
                        points.Add(new PointF(begin + 3, 0));
                        points.Add(new PointF(begin + itemWidth - 3 - Height / 2.0f, 0));       //\
                        points.Add(new PointF(begin + itemWidth - 3, Height / 2.0f));           //-
                        points.Add(new PointF(begin + itemWidth - 3 - Height / 2.0f, Height));  ///
                        points.Add(new PointF(begin + 3, Height));
                        points.Add(new PointF(begin + 3 + Height / 2.0f, Height / 2.0f));
                        points.Add(new PointF(begin + 3, 0));
                    }

                    Point[] pts = new Point[points.Count];
                    for (int i = 0; i < points.Count; i++)
                    {
                        pts[i] = new Point((int)points[i].X, (int)points[i].Y);
                    }

                    if (!ClickArea.ContainsKey(index))
                    {
                        ClickArea.TryAdd(index, pts);
                    }
                    else
                    {
                        ClickArea[index] = pts;
                    }

                    using (Brush br = new SolidBrush(index <= ItemIndex ? SelectedColor : UnSelectedColor))
                    {
                        e.Graphics.FillPolygon(br, points.ToArray());
                    }

                    e.Graphics.DrawString(item.ToString(), Font, new SolidBrush( index <= ItemIndex ? ForeColor : UnSelectedForeColor), begin + (itemWidth - sf.Width) / 2.0f, (Height - sf.Height) / 2.0f);

                    begin = begin + itemWidth - 3 - Height / 2.0f + Interval;
                    index++;
                }
            }
            

        //e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        //e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
        //e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
        //e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
        //Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
        //var path = GetRoundedRectPath(rect);
        //this.Region = new Region(path);

        ////var pa = RectPath(rect);
        ////this.Region = new Region(pa);
        //Color baseColor = this.BackColor;

        //using (SolidBrush b = new SolidBrush(baseColor))
        //{
        //    e.Graphics.FillPath(b, path);
        //    //e.Graphics.FillPath(b, pa);
        //    System.Drawing.Font fo = new System.Drawing.Font(this.Font.Name, this.Font.Size);
        //    Brush brush = new SolidBrush(this.ForeColor);
        //    Pen penn = new Pen(brush, 3);
        //    StringFormat gs = new StringFormat();
        //    gs.Alignment = StringAlignment.Center; //居中
        //    gs.LineAlignment = StringAlignment.Center;//垂直居中
        //    e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
        //    e.Graphics.DrawString(this.Text, fo, brush, rect, gs);
        //}

    }
        
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            if(!isMannual)
            {
                return;
            }
            foreach (KeyValuePair<int, Point[]> item in ClickArea)
            {
                if (e.Location.InRegion(item.Value))
                {
                    ItemIndex = item.Key;
                    break;
                }
            }
        }
        public void ShowStep(ShowSocketStep data)
        {
            if(data.SocketName == this.Name)
            {
                Items = data.Steps;
                ItemIndex = data.CurrentStep;
            }
        }
        private void Steps_Load(object sender, EventArgs e)
        {
            try
            {
                UIDATALayer.UIDATALayerHelper.RegistAction<ShowSocketStep>(nameof(ShowSocketStep), ShowStep).Start();
            }
            catch
            {

            }
            
        }
    }
}
